﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "GnufBase.h"
#include <QtWidgets/QWidget>
#include "GnufPreferenceEntries.h"

class QLabel;
class QPushButton;

namespace gnuf {
    
    /// \brief QtPreferenceEntry class is the basic class.
    class GNUF_BASE_EXPORT QtPreferenceEntry
    {
    protected:
        QtPreferenceEntry(PreferenceEntry * pEntry);
        virtual ~QtPreferenceEntry();

    public:
        /// \return Return the pointer to the PreferenceEntry.
        const PreferenceEntry * preferenceEntry() const;
        
        /// \return Return the pointer to the PreferenceEntry.
        PreferenceEntry * preferenceEntry();

        /// \brief Get it called before show.
        virtual void aboutToShow() = 0;

        /// \return Return the Qt widget that implements using a Qt widget.
        virtual QWidget * asQtWidget() = 0;

    private:
        gcmp::WeakPtr< PreferenceEntry > m_wpPreferenceEntry;
    };
    
    template <class TQtClass>
    class QtPreferenceEntryWith
        : public TQtClass
        , public QtPreferenceEntry
    {
    protected:
        explicit QtPreferenceEntryWith(PreferenceEntry * pEntry)
            : QtPreferenceEntry(pEntry)
        {}
        virtual ~QtPreferenceEntryWith() {}
    };
    
    /// \brief QtThemePreferenceEntry class is the Qt UI implementation
    /// of ThemePreferenceEntry class.
    class GNUF_BASE_EXPORT QtThemePreferenceEntry
        : public QtPreferenceEntryWith<QWidget>
    {
        Q_OBJECT
        
    public:
        explicit QtThemePreferenceEntry(
            PreferenceEntry * pPreferenceEntry,
            const std::vector< std::wstring > & images,
            const int selectedImageIndex);
        virtual ~QtThemePreferenceEntry();
        
        /// \brief Set a callback function that gets called when the selected
        /// image is changed.
        typedef std::function< void(int /* imageIndex */, PreferenceEntry *) > OnImageSelected;
        void setOnImageSelected(const QtThemePreferenceEntry::OnImageSelected &);

        /// \brief Set a callback function that gets called when want to synchronize
        /// the PreferenceEntry instance with the Qt instance.
        typedef std::function< void(const PreferenceEntry *, QtThemePreferenceEntry *) > OnAboutToShow;
        void setOnAboutToShow(const QtThemePreferenceEntry::OnAboutToShow &);

        // Inherits from QtPreferenceEntry...
        virtual void aboutToShow() override final;
        virtual QWidget * asQtWidget() override final { return this; }

        /// \brief Set which image selected.
        /// \param imageIndex: It is the index at which an image is.
        void setImageSelected(int imageIndex) { _setImageSelected(imageIndex, false); }

        /// \return the index of the selected image.
        int selectedImageIndex() const { return m_selectedImageIndex; }
        
    protected:
        // Give the derived class an opportunity to do something...
        virtual void onImageSelected(int imageIndex) {}
        virtual void onAboutToShow(QtThemePreferenceEntry *) {}
        
    private slots:
        void onBtnClicked(bool);
        
    private:
        void _setImageSelected(int imageIndex, bool wantToNotify);
    
        int m_selectedImageIndex;
        QtThemePreferenceEntry::OnImageSelected m_onImageSelected;
        QtThemePreferenceEntry::OnAboutToShow m_onAboutToShow;
        
        QLabel * m_qtLabel;
        std::vector<QPushButton *> m_qtButtons;
    };
}
